import { VuexModule, Module, Action, Mutation, getModule } from 'vuex-module-decorators'
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/cookies'
import index, { resetRouter } from '@/router'
import { PermissionModule } from './permission'
import { TagsViewModule } from './tags-view'
import store from '@/store'
import { getStore, setStore, removeStore } from '@/utils/store.ts'
import { encryption } from '@/utils'
import { Message } from 'element-ui'

export interface IUserState {
  avatar: string
  userInfo: any
  permissions: any
  roles: string[] | number[]
  access_token: string,
  refresh_token: string,
  tenant_id: number
}

interface IList {
  [key: string]: boolean,
}

@Module({ dynamic: true, store, namespaced: true, name: 'user' })
class User extends VuexModule implements IUserState {
  public avatar = ''
  public userInfo = getStore({ name: 'userInfo' }) || {}
  public permissions = getStore({ name: 'permissions' }) || {}
  public roles = getStore({ name: 'roles' }) || []
  public access_token = getStore({ name: 'access_token' }) || ''
  public refresh_token = getStore({ name: 'refresh_token' }) || ''
  public tenant_id = 210

  @Mutation
  private SET_ACCESS_TOKEN(access_token: string) {
    this.access_token = access_token
    setStore({ name: 'access_token', content: this.access_token, type: 'session' })
  }

  @Mutation
  private SET_USER_INFO(userInfo: any) {
    this.userInfo = userInfo
    setStore({
      name: 'userInfo',
      content: this.userInfo,
      type: 'session'
    })
  }

  @Mutation
  private SET_REFRESH_TOKEN(rfToken: string) {
    this.refresh_token = rfToken
    setStore({
      name: 'refresh_token',
      content: this.refresh_token,
      type: 'session'
    })
  }

  @Mutation
  private SET_TENANT_ID(tenant_id: number) {
    this.tenant_id = tenant_id
    setStore({
      name: 'tenant_id',
      content: this.tenant_id,
      type: 'session'
    })
  }

  @Mutation
  private SET_ROLES(roles: any) {
    this.roles = roles
    setStore({
      name: 'roles',
      content: this.roles,
      type: 'session'
    })
  }

  @Mutation
  private SET_PERMISSIONS(permissions: Array<string>) {
    const list: IList = {}
    for (let i = 0; i < permissions.length; i++) {
      list[permissions[i]] = true
    }
    this.permissions = list
    setStore({
      name: 'permissions',
      content: this.permissions,
      type: 'session'
    })
  }

  // 删除token和localStore
  @Mutation
  private REMOVE_TOKEN() {
    // debugger
    this.access_token = ''
    this.refresh_token = ''
    this.permissions = []
    this.userInfo = {}
    this.roles = []
    this.tenant_id = 210
    removeStore({ name: 'access_token' })
    removeStore({ name: 'refresh_token' })
    removeStore({ name: 'userInfo' })
    removeStore({ name: 'tenant_id' })
    removeStore({ name: 'roles' })
    removeStore({ name: 'permissions' })
    removeStore({ name: 'routes' })
  }

  @Action
  public LoginByUsername(userInfo: object) {
    return new Promise((resolve, reject) => {
      const user: any = encryption({
        data: userInfo,
        key: 'samssamssamssams',
        param: ['password']
      })
      login(user.username, user.password, '1', user.TENANT_ID).then(response => {
        const data = response
        if (data.code === 0) {
          Message({
            message: data.msg,
            type: 'error',
            duration: 5 * 1000
          })
          reject(data.msg)
        } else {
          setToken(data.access_token)
          this.SET_ACCESS_TOKEN(data.access_token)
          this.SET_REFRESH_TOKEN(data.refresh_token)
          this.SET_TENANT_ID(data.tenant_id)
          resolve()
        }
      }).catch(error => {
        reject(error)
      })
    })
  }

  @Action
  public ResetToken() {
    // removeToken()
    this.REMOVE_TOKEN()
  }

  @Action
  public GetUserInfo(): Promise<any> {
    // 接口读取用户信息
    return new Promise((resolve, reject) => {
      getInfo().then(response => {
        console.log('接口获取用户信息', response.data)
        const data = response.data
        if (!data) {
          reject(response.msg)
        }
        const { roles, sysUser, permissions } = data
        // roles must be a non-empty array
        if (!roles || roles.length <= 0) {
          reject('getInfo: roles must be a non-null array!')
        }
        this.SET_ROLES(roles)
        this.SET_USER_INFO(sysUser)
        this.SET_PERMISSIONS(permissions)
        resolve(response)
      }).catch(error => {
        console.log('请求用户详情报错', error)
        reject(error)
      })
    })
  }

  @Action
  public async ChangeRoles(role: string) {
    // Dynamically modify permissions
    const token = role + '-token'
    setToken(token)
    // setToken(token)
    await this.GetUserInfo()
    resetRouter()
    // Generate dynamic accessible routes based on roles
    await PermissionModule.GenerateRoutes(this.roles)
    // Add generated routes
    index.addRoutes(PermissionModule.dynamicRoutes)
    // Reset visited views and cached views
    TagsViewModule.delAllViews()
  }

  @Action
  public LogOut(): Promise<any> {
    return logout().then(() => {
      this.SET_ACCESS_TOKEN('')
      this.SET_ROLES([])
      // 清除权限
      this.SET_PERMISSIONS([])
      // 清除用户信息
      this.SET_USER_INFO({})
      this.SET_REFRESH_TOKEN('')
      this.SET_ROLES([])
      removeToken()
    })
    // commit('tags/DEL_ALL_TAG', {}, { root: true })
  }

  // 注销session
  @Action
  public FedLogOut() {
    return logout().then((res) => {
      this.SET_ACCESS_TOKEN('')
      this.SET_ROLES([])
      // 清除权限
      this.SET_PERMISSIONS([])
      // 清除用户信息
      this.SET_USER_INFO({})
      this.SET_REFRESH_TOKEN('')
      this.SET_ROLES([])
      removeToken()
      return Promise.resolve()
    }).catch(error => {
      return Promise.reject(error)
    })
  }
}

export const UserModule = getModule(User)
